package com.ruoyi.task.service.impl;

import java.util.*;
import java.util.stream.Collectors;


import com.alibaba.fastjson.JSONArray;
import com.ruoyi.common.constant.SysConstants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.TaskStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.SnowflakeUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.task.domain.*;
import com.ruoyi.task.mapper.*;
import com.ruoyi.task.service.ISysUserTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.task.service.ISysTaskService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 任务Service业务层处理
 * 
 * @author yjf
 * @date 2022-06-30
 */
@Service
public class SysTaskServiceImpl implements ISysTaskService 
{
    @Autowired
    private SysTaskMapper sysTaskMapper;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private ISysUserTaskService userTaskService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysTaskPropMapper taskPropMapper;

    @Autowired
    private SysFaultMapper sysFaultMapper;

    @Autowired
    private SysStepMapper sysStepMapper;

    @Autowired
    private SysTaskStepMapper sysTaskStepMapper;



    /**
     * 查询任务
     * 
     * @param taskId 任务主键
     * @return 任务
     */
    @Override
    public SysTask selectSysTaskByTaskId(Long taskId)
    {
        SysTask taskInfo = sysTaskMapper.selectSysTaskByTaskId(taskId);
        //统计时长
        if (taskInfo.getStartTime() != null && taskInfo.getSubmitTime() != null) {
            String diffTime = DateUtils.getTaskDatePoor(taskInfo.getSubmitTime(), taskInfo.getStartTime());
            taskInfo.setDurationTime(diffTime);
        }

        if(StringUtils.isNotBlank(taskInfo.getDeptIds())){
            List<Long> deptIds = Arrays.stream(taskInfo.getDeptIds().split(","))
                    .map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
            taskInfo.setDeptIdsList(deptIds);
        }
        SysTaskProp sysTaskProp = new SysTaskProp();
        sysTaskProp.setTaskNo(taskInfo.getTaskNo());
        List<SysTaskProp> taskPropList = taskPropMapper.selectTaskProp(sysTaskProp);
        taskInfo.setPropNumOptions(taskPropList);
        return taskInfo;
    }

    /**
     * 查询任务列表
     * 
     * @param sysTask 任务
     * @return 任务
     */
    @Override
    public List<SysTask> selectSysTaskList(SysTask sysTask)
    {
        List<SysTask> taskList =sysTaskMapper.selectSysTaskList(sysTask);
        //单位列表
        SysDept dept =new SysDept();
        dept.setDeptId(SecurityUtils.getDeptId());
        List<SysDept> deptList = deptService.selectDeptList(dept);
        //构建参训单位名称
        for (SysTask task : taskList) {
            StringBuffer deptName = new StringBuffer();
            if(StringUtils.isNotBlank(task.getDeptIds())){
                String[] deptIds = task.getDeptIds().split(",");
                for (String deptId : deptIds) {
                    for (SysDept de : deptList) {
                        if(de.getDeptId().equals(Long.parseLong(deptId))){
                            deptName.append(",");
                            deptName.append(de.getDeptName());
                        }
                    }
                }
                if (StringUtils.isNotBlank(deptName.toString())) {
                    task.setDeptName(deptName.toString().substring(1));
                }
            }
            if (task.getStartTime() != null && task.getSubmitTime() != null) {
                String diffTime = DateUtils.getTaskDatePoor(task.getSubmitTime(), task.getStartTime());
                task.setDurationTime(diffTime);
            }
        }
        return taskList;
    }

    /**
     * 新增任务
     * 
     * @param sysTask 任务
     * @return 结果
     */
    @Override
    @Transactional
    public int insertSysTask(SysTask sysTask) {
        //组装任务参数
        Long taskNo = SnowflakeUtils.snowflakeId();
        sysTask.setTaskNo(taskNo);  //任务编号
        sysTask.setUserId(SecurityUtils.getUserId());   //创建任务的用户ID
        sysTask.setDeptId(SecurityUtils.getDeptId());   //创建任务的用户单位ID
        String deptIds = StringUtils.join(sysTask.getDeptIdsList(), ",");
        sysTask.setDeptIds(deptIds);  //参训单位ID集合
        sysTask.setCreateTime(DateUtils.getNowDate());
        sysTask.setUpdateTime(DateUtils.getNowDate());
        //新增任务-地物关系表
        List<SysTaskProp> taskPropList = JSONArray.parseArray(sysTask.getPropNumStr(), SysTaskProp.class);
        if (taskPropList.size() > 0) {
            List<Long> propIds = taskPropList.stream().map(t -> t.getPropId()).distinct().collect(Collectors.toList());
            if (taskPropList.size() != propIds.size()) {
                throw new ServiceException("地物设置不能设置相同项！");
            }

            List<SysTaskProp> batchList = new ArrayList<>();
            for (SysTaskProp taskProp : taskPropList) {
                SysTaskProp sysTaskProp = new SysTaskProp();
                if (StringUtils.isNotNull(taskProp.getPropId()) && StringUtils.isNotNull(taskProp.getPropNum())) {
                    sysTaskProp.setTaskNo(sysTask.getTaskNo());
                    sysTaskProp.setPropId(taskProp.getPropId());
                    sysTaskProp.setPropNum(taskProp.getPropNum());
                    batchList.add(sysTaskProp);
                }
            }
            if (batchList.size() > 0) {
                taskPropMapper.batchTaskProp(batchList);
            }
        }
        //故障现象,组装数据
        List<SysFault> faultList = JSONArray.parseArray(sysTask.getCauseStr(), SysFault.class);
        if (faultList.size() > 0) {
            List<SysFault> faultL = new ArrayList<>();
            for (SysFault fault : faultList) {
                SysFault sysFault = new SysFault();
                sysFault.setTaskNo(sysTask.getTaskNo());
                sysFault.setChildName(fault.getChildName());
                sysFault.setWeight(fault.getWeight());
                sysFault.setStatus(fault.getStatus());
                sysFault.setCreateTime(DateUtils.getNowDate());
                sysFault.setUpdateTime(DateUtils.getNowDate());
                faultL.add(sysFault);
            }
            if (faultL.size() > 0) {
                //新增故障现象
                sysFaultMapper.batchSysFault(faultL);
            }

            //根据难度、故障现象ID集合查询步骤列表写入步骤
            Long[] deptStepIds = faultList.stream().map(SysFault::getDeptId).toArray(Long[]::new);
            if (deptStepIds.length > 0) {
                SysStep sysStep = new SysStep();
                sysStep.setDeptIds(deptStepIds);
                //难度
                if (SysConstants.CONSTANT_STR1.equals(sysTask.getTaskDifficulty().toString())) {
                    sysStep.setSimply("1");
                } else if (SysConstants.CONSTANT_STR2.equals(sysTask.getTaskDifficulty().toString())) {
                    sysStep.setOrdinary("1");
                } else if (SysConstants.CONSTANT_STR3.equals(sysTask.getTaskDifficulty().toString())) {
                    sysStep.setDifficulte("1");
                }
                List<SysStep> stepList = sysStepMapper.selectSysStepList(sysStep);
                //批量新增任务的步骤列表
                if (stepList.size() > 0) {
                    List<SysTaskStep> taskStepInsert = new ArrayList<>();
                    for (SysStep step : stepList) {
                        SysTaskStep taskStep = new SysTaskStep();
                        BeanUtils.copyProperties(step, taskStep);
                        taskStep.setTaskNo(taskNo);
                        taskStep.setCreateTime(DateUtils.getNowDate());
                        taskStep.setUpdateTime(DateUtils.getNowDate());
                        taskStepInsert.add(taskStep);
                    }
                    if (taskStepInsert.size() > 0) {
                        sysTaskStepMapper.batchSysTaskStep(taskStepInsert);
                    }
                }
            }
        }

        //新增任务
        return sysTaskMapper.insertSysTask(sysTask);
    }

    /**
     * 复制任务
     * @param sysTask
     * @return
     */
    @Override
    @Transactional
    public int cloneSysTask(SysTask sysTask)
    {

        SysTask taskInfo = sysTaskMapper.selectSysTaskByTaskId(sysTask.getTaskId());

        if(StringUtils.isNull(taskInfo)){
            throw new ServiceException("原任务数据不存在！");
        }
        //组装任务参数
        Long taskNo = SnowflakeUtils.snowflakeId();
        taskInfo.setTaskNo(taskNo);  //任务编号
        taskInfo.setUserId(SecurityUtils.getUserId());   //创建任务的用户ID
        taskInfo.setDeptId(SecurityUtils.getDeptId());   //创建任务的用户单位ID
        taskInfo.setStatus(SysConstants.CONSTANT_INT1);     //默认停用状态
        taskInfo.setTaskStatus(TaskStatus.NOS.getValue());     //任务状态
        taskInfo.setGrade(null);    //平均成绩
        taskInfo.setUrl(null);      //视频链接
        taskInfo.setHeadcount(SysConstants.CONSTANT_INT0);  //参与人数
        taskInfo.setStartTime(null);
        taskInfo.setSubmitTime(null);
        taskInfo.setCreateTime(DateUtils.getNowDate());
        taskInfo.setUpdateTime(DateUtils.getNowDate());

        //复制任务-地物关系表
        SysTaskProp sysTaskProp = new SysTaskProp();
        sysTaskProp.setTaskNo(sysTask.getTaskNo());
        List<SysTaskProp> taskPropList= taskPropMapper.selectTaskProp(sysTaskProp);
        if (taskPropList.size() > 0)
        {
            for (SysTaskProp taskProp : taskPropList) {
                taskProp.setTaskNo(taskNo);
            }
            taskPropMapper.batchTaskProp(taskPropList);
        }

        //故障现象,组装数据
        SysFault faultParam = new SysFault();
        faultParam.setTaskNo(sysTask.getTaskNo());
        List<SysFault> faultList = sysFaultMapper.selectSysFaultList(faultParam);
        int percent = 0;
        if (faultList.size() > 0) {
            List<SysFault> faultL = new ArrayList<>();
            for (SysFault fault : faultList) {
                SysFault sysFault = new SysFault();
                sysFault.setTaskNo(taskNo); //新的任务编号
                sysFault.setChildName(fault.getChildName());
                sysFault.setWeight(fault.getWeight());
                sysFault.setStatus(fault.getStatus());
                sysFault.setCreateTime(DateUtils.getNowDate());
                sysFault.setUpdateTime(DateUtils.getNowDate());
                faultL.add(sysFault);
                percent = percent + fault.getWeight();
            }

            if (percent > 100 || percent < 0) {
                throw new ServiceException("百分数累加不能超过100%且不能小于0！");
            }

            //新增故障现象
            if (faultL.size() > 0) {
                sysFaultMapper.batchSysFault(faultL);
            }
            //查询原任务的步骤列表
            SysTaskStep sysTaskStep = new SysTaskStep();
            sysTaskStep.setTaskNo(sysTask.getTaskNo());
            sysTaskStep.setDelFlag(SysConstants.CONSTANT_STR0);
            List<SysTaskStep> taskStepList = sysTaskStepMapper.selectSysTaskStepList(sysTaskStep);
            //批量新增任务的步骤列表
            if (taskStepList.size() > 0) {
                List<SysTaskStep> taskStepInsert = new ArrayList<>();
                for (SysTaskStep step : taskStepList) {
                    SysTaskStep taskStep = new SysTaskStep();
                    BeanUtils.copyProperties(step, taskStep);
                    taskStep.setTaskNo(taskNo);
                    taskStep.setCreateTime(DateUtils.getNowDate());
                    taskStep.setUpdateTime(DateUtils.getNowDate());
                    taskStepInsert.add(taskStep);
                }
                if (taskStepInsert.size() > 0) {
                    sysTaskStepMapper.batchSysTaskStep(taskStepInsert);
                }
            }
        }
        //新增任务
        return sysTaskMapper.insertSysTask(taskInfo);
    }

    /**
     * 修改任务
     * 
     * @param sysTask 任务
     * @return 结果
     */
    @Override
    @Transactional
    public int updateSysTask(SysTask sysTask)
    {

        //组装任务参数
        sysTask.setUserId(SecurityUtils.getUserId());   //创建任务的用户ID
        sysTask.setDeptId(SecurityUtils.getDeptId());   //创建任务的用户单位ID
        String deptIds = StringUtils.join(sysTask.getDeptIdsList(), ",");
        sysTask.setDeptIds(deptIds);  //参训单位ID集合
        sysTask.setUpdateTime(DateUtils.getNowDate());
        //删除任务-地物关系表
        taskPropMapper.deleteTaskPropByTaskNo(sysTask.getTaskNo());
        //新增任务-地物关系表
        List<SysTaskProp> taskPropList= JSONArray.parseArray(sysTask.getPropNumStr(),SysTaskProp.class);
        if (taskPropList.size() > 0)
        {
            List<Long> propIds = taskPropList.stream().map(t->t.getPropId()).distinct().collect(Collectors.toList());
            if (taskPropList.size() != propIds.size())
            {
                throw new ServiceException("地物设置不能设置相同项！");
            }

            List<SysTaskProp> batchList = new ArrayList<>();
            for (SysTaskProp taskProp : taskPropList) {
                SysTaskProp sysTaskProp =new SysTaskProp();
                if(StringUtils.isNotNull(taskProp.getPropId()) && StringUtils.isNotNull(taskProp.getPropNum())){
                    sysTaskProp.setTaskNo(sysTask.getTaskNo());
                    sysTaskProp.setPropId(taskProp.getPropId());
                    sysTaskProp.setPropNum(taskProp.getPropNum());
                    batchList.add(sysTaskProp);
                }
            }
            if (batchList.size() > 0)
            {
                taskPropMapper.batchTaskProp(batchList);
            }
        }

        //故障现象,组装数据
        List<SysFault> faultList = JSONArray.parseArray(sysTask.getCauseStr(), SysFault.class);
        int percent =0;
        if (faultList.size() > 0) {
            List<SysFault> faultL = new ArrayList<>();
            for (SysFault fault : faultList) {
                SysFault sysFault = new SysFault();
                sysFault.setTaskNo(sysTask.getTaskNo());
                sysFault.setChildName(fault.getChildName());
                sysFault.setWeight(fault.getWeight());
                sysFault.setStatus(fault.getStatus());
                sysFault.setCreateTime(DateUtils.getNowDate());
                sysFault.setUpdateTime(DateUtils.getNowDate());
                faultL.add(sysFault);
                percent = percent+fault.getWeight();
            }

            if (percent > 100 || percent < 0) {
                throw new ServiceException("百分数累加不能超过100%且不能小于0！");
            }

            //新增故障现象
            if (faultL.size() > 0) {
                //删除故障现象
                sysFaultMapper.deleteSysFaultByTaskNo(sysTask.getTaskNo());
                sysFaultMapper.batchSysFault(faultL);
            }

            //根据难度、故障现象ID集合查询步骤列表写入步骤
            Long[] deptStepIds = faultList.stream().map(SysFault::getDeptId).toArray(Long[]::new);
            if (deptStepIds.length > 0) {
                SysStep sysStep = new SysStep();
                sysStep.setDeptIds(deptStepIds);
                //难度
                if (SysConstants.CONSTANT_STR1.equals(sysTask.getTaskDifficulty().toString())) {
                    sysStep.setSimply("1");
                } else if (SysConstants.CONSTANT_STR2.equals(sysTask.getTaskDifficulty().toString())) {
                    sysStep.setOrdinary("1");
                } else if (SysConstants.CONSTANT_STR3.equals(sysTask.getTaskDifficulty().toString())) {
                    sysStep.setDifficulte("1");
                }
                List<SysStep> stepList = sysStepMapper.selectSysStepList(sysStep);
                //组装新增的数据
                if (stepList.size() > 0) {
                    List<SysTaskStep> taskStepInsert = new ArrayList<>();
                    for (SysStep step : stepList) {
                        SysTaskStep taskStep = new SysTaskStep();
                        BeanUtils.copyProperties(step, taskStep);
                        taskStep.setTaskNo(sysTask.getTaskNo());
                        taskStep.setCreateTime(DateUtils.getNowDate());
                        taskStep.setUpdateTime(DateUtils.getNowDate());
                        taskStepInsert.add(taskStep);
                    }
                    //批量删除任务的步骤列表
                    sysTaskStepMapper.deleteTaskStepByTaskNo(sysTask.getTaskNo());
                    //批量新增任务的步骤列表
                    if (taskStepInsert.size() > 0) {
                        sysTaskStepMapper.batchSysTaskStep(taskStepInsert);
                    }
                }
            }

        }
        return sysTaskMapper.updateSysTask(sysTask);
    }




    /**
     * 修改任务启用状态
     * 停止后无法重新启用
     * @param sysTask 任务
     * @return 结果
     */
    @Override
    @Transactional
    public int changeTaskStatus(SysTask sysTask) {
        Long taskId = sysTask.getTaskId();
        Integer status = sysTask.getStatus();
        SysTask taskInfo = sysTaskMapper.selectSysTaskByTaskId(taskId);
        if(StringUtils.isEmpty(taskInfo.getDeptIds())){
            throw new ServiceException("参训单位不能为空！");
        }

        //只有任务状态为已创建的任务才能启用(不能二次启用)
        if (status.equals(SysConstants.CONSTANT_INT0)
                && taskInfo.getStatus().equals(TaskStatus.NOS.getValue())
                && taskInfo.getTaskStatus().equals(TaskStatus.NOS.getValue())) {

            //查询对应单位的个人ID
            List<Long> deptIds = Arrays.stream(taskInfo.getDeptIds().split(","))
                    .map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
            SysUser sysUser =new SysUser();
            sysUser.setDeptIds(deptIds);
            List<SysUser> userList = userService.selectUserList(sysUser);
            if (userList.size() < 1)
            {
                throw new ServiceException("当前选择参训单位的人员不能为空！");
            }
            //组装数据,批量插入用户任务数据
            List<SysUserTask> userTaskList = new ArrayList<>();
            for (SysUser user : userList)
            {
                SysUserTask userTask = new SysUserTask();
                userTask.setTaskNo(taskInfo.getTaskNo());       //任务编号
                userTask.setUserId(user.getUserId());           //用户ID
                userTask.setDeptId(user.getDeptId());           //用户单位ID
                userTask.setStatus(SysConstants.CONSTANT_INT0);     //默认选择
                userTask.setTaskStatus(TaskStatus.NOS.getValue());  //默认已创建
                userTask.setCreateTime(DateUtils.getNowDate());
                userTaskList.add(userTask);
            }
            userTaskService.insertSysUserTaskAll(userTaskList);
            //启用状态更新为开始，任务表的任务状态更新为准备中，通知玩家(待定)

            sysTask.setHeadcount(userTaskList.size());  //总人数
            sysTask.setTaskStatus(TaskStatus.AFOOT.getValue());
            sysTask.setUpdateTime(DateUtils.getNowDate());
            return sysTaskMapper.updateSysTask(sysTask);
        } else if (status.equals(SysConstants.CONSTANT_INT1)) {
            //强制停止任务，删除个人任务记录、更新任务状态为已终止
            SysUserTask userTask = new SysUserTask();
            userTask.setTaskNo(taskInfo.getTaskNo());
            userTask.setUpdateTime(DateUtils.getNowDate());
            userTaskService.deleteUserTask(userTask);
            sysTask.setTaskStatus(TaskStatus.TERMINATE.getValue());
            sysTask.setUpdateTime(DateUtils.getNowDate());
            return sysTaskMapper.updateSysTask(sysTask);
        } else {
            throw new ServiceException("如需重新开始任务可复制当前任务！");
        }
    }

    /**
     * 批量删除任务
     * 
     * @param taskIds 需要删除的任务主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteSysTaskByTaskIds(Long[] taskIds)
    {
        List<SysTask> taskList=sysTaskMapper.selectSysTaskByTaskIds(taskIds);
        List<Long> taskNos = taskList.stream().map(t->t.getTaskNo()).collect(Collectors.toList());
        //删除任务和物品关系
        taskPropMapper.deleteTaskProp(taskNos);
        return sysTaskMapper.deleteSysTaskByTaskIds(taskIds);
    }

    /**
     * 删除任务信息
     * 
     * @param taskId 任务主键
     * @return 结果
     */
    @Override
    public int deleteSysTaskByTaskId(Long taskId)
    {
        SysTask task=sysTaskMapper.selectSysTaskByTaskId(taskId);
        //删除任务和物品关系
        taskPropMapper.deleteTaskPropByTaskNo(task.getTaskNo());
        return sysTaskMapper.deleteSysTaskByTaskId(taskId);
    }
}
